package com.daffodil.devtool.generator;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.velocity.VelocityContext;
import org.hibernate.id.UUIDHexGenerator;

import com.daffodil.devtool.constant.DevtoolConstant;
import com.daffodil.devtool.entity.GenTable;
import com.daffodil.devtool.entity.GenTableColumn;
import com.daffodil.util.StringUtils;

import cn.hutool.core.date.DateUtil;

/**
 * -代码生成器 工具类
 * @author yweijian
 * @date 2022年3月4日
 * @version 1.0
 * @description
 */
public class VelocityUtils {
    
    /**
     * 设置模板变量信息
     * 
     * @return 模板列表
     */
    public static VelocityContext prepareContext(GenTable genTable) {
        String moduleName = genTable.getModuleName();
        String businessName = genTable.getBusinessName();
        String packageName = genTable.getPackageName();
        String tplCategory = genTable.getTplCategory();
        String functionName = genTable.getFunctionName();

        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("tplCategory", genTable.getTplCategory());
        velocityContext.put("tableName", genTable.getTableName());
        velocityContext.put("functionApi", genTable.getFunctionApi());
        velocityContext.put("FunctionApi", genTable.getFunctionApi().toUpperCase());
        velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】");
        velocityContext.put("ClassName", genTable.getClassName());
        velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
        velocityContext.put("moduleName", genTable.getModuleName());
        velocityContext.put("businessName", genTable.getBusinessName());
        velocityContext.put("basePackage", getPackagePrefix(packageName));
        velocityContext.put("packageName", packageName);
        velocityContext.put("author", genTable.getFunctionAuthor());
        velocityContext.put("datetime", DateUtil.formatDate(new Date()));
        velocityContext.put("pkColumn", genTable.getPkColumn());
        velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
        velocityContext.put("columns", genTable.getColumns());
        velocityContext.put("table", genTable);
        velocityContext.put("menuIds", getMenuIds(6));
        if (DevtoolConstant.TPL_TREE.equals(tplCategory)) {
            setTreeVelocityContext(velocityContext, genTable);
        }
        velocityContext.put("stringUtils", new StringUtils());//字符串处理工具
        return velocityContext;
    }

    public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) {
        context.put("treeCode", genTable.getTreeCode());
        context.put("treeParentCode", genTable.getTreeParentCode());
        context.put("treeName", genTable.getTreeName());
        context.put("expandColumn", getExpandColumn(genTable));
        context.put("tree_parent_code", genTable.getTreeParentCode());
        context.put("tree_name", genTable.getTreeName());
    }

    /**
     * 获取模板信息
     * 
     * @return 模板列表
     */
    public static List<String> getTemplateList(GenTable genTable) {
        List<String> templates = new ArrayList<String>();
        templates.add("vm/" + genTable.getTplCodehouse() + "/java/entity.java.vm");
        templates.add("vm/" + genTable.getTplCodehouse() + "/java/service.java.vm");
        templates.add("vm/" + genTable.getTplCodehouse() + "/java/serviceImpl.java.vm");
        templates.add("vm/" + genTable.getTplCodehouse() + "/java/controller.java.vm");
        templates.add("vm/" + genTable.getTplCodehouse() + "/html/index.ts.vm");
        templates.add("vm/" + genTable.getTplCodehouse() + "/html/index.vue.vm");
        templates.add("vm/" + genTable.getTplCodehouse() + "/html/add.vue.vm");
        templates.add("vm/" + genTable.getTplCodehouse() + "/html/edit.vue.vm");
        templates.add("vm/" + genTable.getTplCodehouse() + "/sql/sql.vm");
        return templates;
    }

    /**
     * 获取文件名
     */
    public static String getFileName(String template, GenTable genTable) {
        // 文件名称
        String fileName = "";
        // 包路径
        String packageName = genTable.getPackageName();
        // 模块名
        String moduleName = genTable.getModuleName();
        // 大写类名
        String className = genTable.getClassName();
        // 业务名称
        String businessName = genTable.getBusinessName();

        String javaPath = "src/main/java/" + StringUtils.replace(packageName, ".", "/");
        String apiPath = "src/api/" + moduleName + "/" + businessName;
        String vuePath = "src/view/" + moduleName + "/" + businessName;

        if (template.contains("entity.java.vm")) {
            fileName = StringUtils.format("{}/entity/{}.java", javaPath, className);
        } else if (template.contains("service.java.vm")) {
            fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
        } else if (template.contains("serviceImpl.java.vm")) {
            fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
        } else if (template.contains("controller.java.vm")) {
            fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className);
        } else if (template.contains("index.ts.vm")) {
            fileName = StringUtils.format("{}/index.ts", apiPath);
        } else if (template.contains("index.vue.vm")) {
            fileName = StringUtils.format("{}/index.vue", vuePath);
        } else if (template.contains("add.vue.vm")) {
            fileName = StringUtils.format("{}/add{}.vue", vuePath, className);
        } else if (template.contains("edit.vue.vm")) {
            fileName = StringUtils.format("{}/edit{}.vue", vuePath, className);
        } else if (template.contains("sql.vm")) {
            fileName = businessName + "Menu.sql";
        }
        return fileName;
    }

    /**
     * 获取包前缀
     * 
     * @param packageName
     *            包名称
     * @return 包前缀名称
     */
    public static String getPackagePrefix(String packageName) {
        int lastIndex = packageName.lastIndexOf(".");
        String basePackage = StringUtils.substring(packageName, 0, lastIndex);
        return basePackage;
    }

    /**
     * 获取权限前缀
     * 
     * @param moduleName
     *            模块名称
     * @param businessName
     *            业务名称
     * @return 返回权限前缀
     */
    public static String getPermissionPrefix(String moduleName, String businessName) {
        return StringUtils.format("{}:{}", moduleName, businessName);

    }

    /**
     * 获取需要在哪一列上面显示展开按钮
     * 
     * @param genTable 业务表对象
     * @return 展开按钮列序号
     */
    public static int getExpandColumn(GenTable genTable) {
        String treeName = genTable.getTreeName();
        int num = 0;
        for (GenTableColumn column : genTable.getColumns()) {
            if (column.isList()) {
                num++;
                String columnName = column.getColumnName();
                if (columnName.equals(treeName)) {
                    break;
                }
            }
        }
        return num;
    }
    
    public static List<String> getMenuIds(int count){
        List<String> ids = new ArrayList<String>();
        UUIDHexGenerator uuidHexGenerator = new UUIDHexGenerator();
        for(int i = 0; i < count; i++){
            ids.add(uuidHexGenerator.generate(null, null).toString());
        }
        return ids;
    }
}